package picol.model.memory;

import java.util.Map;
import java.util.TreeMap;
import picol.model.asa.ASAVariable;
import picol.model.asa.expr.ASAExpr;
import picol.model.asa.expr.ASAExprEntier;

/**
 * Classe de gestion de la table des symboles
 * @author Aurélien Marcel - Julien Sanderson
 */
public class TableSymbole {

    private Map<String, ASAExpr> listVar;
    private Map<String, DetailFonc> listFonc;

    public TableSymbole() {
        this.listVar = new TreeMap<String, ASAExpr>();
        this.listFonc = new TreeMap<String, DetailFonc>();
    }

    /**
     * Méthode pour ajouter une nouvelle variable à la table des symboles
     * @param _variable, la variable à ajouter dans la Map
     */
    public void nouvelleVariable(ASAVariable _variable) {
        String nom = _variable.getDeclaration().getIdent();
        ASAExpr valeur = null;
        if (_variable.getExpr() != null) {
            valeur = _variable.getExpr();
        }
        this.listVar.put(nom, valeur);
    }

    /**
     * Méthode pour modifier une variable déjà présente dans la table des symboles
     * @param _nom, nom de la variable à modifier
     * @param _valeur, nouvelle valeur de la variable
     */
    public void modifierVariable(String _nom, ASAExpr _valeur) {
        this.listVar.remove(_nom);
        this.listVar.put(_nom, _valeur);
    }

    /**
     * Méthode pour ajouter une nouvelle fonction à la table des symboles
     * Implémentation incomplète et méthode non utilisée
     * @param nom, nom de la fonction à ajouter
     * @param detailFonction, définition de la fonction
     */
    public void nouvelleFonction(String nom, DetailFonc detailFonction) {
        listFonc.put(nom, detailFonction);
    }

    /**
     * Méthode pour déterminer si une variable existe déjà
     * @param nom, nom de la variable à tester
     * @return vrai si la variable existe déjà, faux sinon
     */
    public boolean existeVariable(String nom) {
        return listVar.containsKey(nom);
    }

    /**
     * Méthode pour déterminer si une fonction existe déjà
     * Méthode non utilisée
     * @param nom, nom de la fonction à tester
     * @return vrai si la fonction existe déjà, faux sinon
     */
    public boolean existeFonction(String nom) {
        return listFonc.containsKey(nom);
    }

    /**
     * Méthode pour récupérer la valeur d'une variable à partir de son nom
     * @param nom, nom de la variable dont la valeur est à récupérer
     * @return la valeur de la variable sous forme d'ASAExpr
     */
    public ASAExpr getValeur(String nom) {
        return listVar.get(nom);
    }

    /**
     * Méthode toString
     * @return
     */
    @Override
    public String toString() {
        String string = "";
        ASAExpr expr = null;
        for (Map.Entry<String, ASAExpr> entry : this.listVar.entrySet()) {
            expr = entry.getValue();
            if (expr instanceof ASAExprEntier) {
                string += " " + entry.getKey() + " : " + expr.getValeur() + "\n";
            }
        }
        return string;
    }
}
